﻿#include "HWUtils.h"
#include <QHostAddress>
#include <QNetworkInterface>
#include <QProcess>
#include <QHostInfo>
#include <QDebug>
#include <QDateTime>
#include <QDir>
#include <QIODevice> 
#include <QTextStream> 
#include <QFile>
#include <QLabel>
#include <QMessageBox>
#include "Configer.h"
#include "HttpUtils.h"

using namespace util;

#pragma region get_hardware_info
QString HwUtils::read_ip_address()
{
    QString ip_address;
    QList<QHostAddress> ipAddressesList = QNetworkInterface::allAddresses();
	for (int i = 0; i < ipAddressesList.size(); ++i)
    {
        if (ipAddressesList.at(i) != QHostAddress::LocalHost &&  ipAddressesList.at(i).toIPv4Address())
        {
            ip_address = ipAddressesList.at(i).toString();
			break;
        }
    }
    if (ip_address.isEmpty())
        ip_address = QHostAddress(QHostAddress::LocalHost).toString();
    return ip_address;
}


QString HwUtils::getBiosId(){
	QString cmdRes = HwUtils::getCmdRes("wmic csproduct get uuid");
	QRegExp regExp("[^\\w\\d-]|[U,u][U,u][I,i][D,d]");
	cmdRes.remove(regExp);
	return cmdRes;
}


QString HwUtils::getCmdRes(QString cmd){
    QProcess p(0);
    p.start("cmd", QStringList()<<"/c"<<cmd);
    p.waitForStarted();
    p.waitForFinished();
    QString strTemp=QString::fromLocal8Bit(p.readAllStandardOutput());
    return strTemp;
}
#pragma endregion get_hardware_info


#pragma region AboutLog
void HwUtils::simpleLog2File(QString fileName, QString body)
{
	QDateTime current_date_time = QDateTime::currentDateTime();
	QString current_date = current_date_time.toString("yyyy.MM.dd hh:mm:ss.zzz");

	QDir* TEST = new QDir;
	bool exist = TEST->exists("log");
	if (!exist)
		bool ok = TEST->mkdir("log");
	QString fileName1 = "log/" + fileName;

	QFile file(fileName1);
	if (!file.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Append))
	{
		qCritical() << "logFile open fail!" << endl;
	}
	QTextStream in(&file);
	current_date += ":" + body;
	in << current_date << "\n";
	file.close();
	delete TEST;
}

void HwUtils::simpleJson2File(QString fileName, QString body)
{
	QDir* TEST = new QDir;
	bool exist = TEST->exists("log");
	if (!exist)
		bool ok = TEST->mkdir("log");
	QString fileName1 = "log/" + fileName;

	QFile file(fileName1);
	if (!file.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Append))
	{
		qCritical() << "logFile open fail!" << endl;
	}
	QTextStream in(&file);
	in << body << "\n";
	file.close();
	delete TEST;
}

// get whether write Debug Log
bool HwUtils::logDebugRequired()
{
	QString debugLogConfig = readGlobalIniConfig("Global/DebugLog");
	if (debugLogConfig.isEmpty()) {
		qInfo() << "debugLogConfig loaded from ini_config is Empty,set debugLogConfig to OFF";
		writeGlobalIniConfig("Global/DebugLog", "OFF");
		return false;
	}
	if (debugLogConfig.toLower() != "on")
	{
		qInfo() << "debugLogConfig loaded from ini_config is not ON. Sys will not write debug log!";
		return false;
	}
	return true;
}
#pragma endregion AboutLog



#pragma region set_page_style

void HwUtils::setLED(QLabel* label, int color, int size)
{
    label->setText("");
    QString min_width = QString("min-width: %1px;").arg(size);           
    QString min_height = QString("min-height: %1px;").arg(size);            
    QString max_width = QString("max-width: %1px;").arg(size);            
    QString max_height = QString("max-height: %1px;").arg(size);          
    QString border_radius = QString("border-radius: %1px;").arg(size/2);   
    QString border = QString("border:1px solid black;"); 

    QString background = "background-color:";
    switch (color) {
    case 0:
        // Grey
        background += "rgb(190,190,190)";
        break;
    case 1:
        // Red
        background += "rgb(255,0,0)";
        break;
    case 2:
        // Green
        background += "rgb(0,255,0)";
        break;
    case 3:
        // Yellow
        background += "rgb(255,255,0)";
        break;
    default:
        break;
    }

    const QString SheetStyle = min_width + min_height + max_width + max_height + border_radius + border + background;
    label->setStyleSheet(SheetStyle);
}
#pragma endregion set_page_style

#pragma region check_params

bool HwUtils::isOkHttpCode(int httpCode) 
{
	return httpCode == 0 || httpCode == 200;
}

bool HwUtils::checkHttpCode(int httpCode)
{
	qInfo() << "HttpCode:" << httpCode;
	if (isOkHttpCode(httpCode))
	{
		return true;
	}
	qCritical() << "rsponse error. retCode is:(" << httpCode << ").";
	QMessageBox::critical(NULL,
		QStringLiteral("错误"), 
		QStringLiteral("网络错误\n错误码:%1 \n原因:%2")
		.arg(httpCode).arg(HttpStatusInfo::getByCode(httpCode).reason));
	return false;
}

bool HwUtils::checkHttpCode(int httpCode, std::string httpMsg)
{
	qInfo() << "HttpCode:" << httpCode << ", httpMsg:" << httpMsg.c_str();
	if (isOkHttpCode(httpCode))
	{
		return true;
	}
	qCritical() << "rsponse error. retCode is:(" << httpCode << ").";
	QMessageBox::critical(NULL, 
		QStringLiteral("错误"), 
		QStringLiteral("网络错误\n错误码:%1, 错误信息:%2 \n原因:%3")
		.arg(httpCode).arg(httpMsg.c_str()).arg(HttpStatusInfo::getByCode(httpCode).reason));
	return false;
}

bool HwUtils::checkSomeParam(QString paraName, QString paraValue)
{
	qInfo() << QString("check Param %1 : %2").arg(paraName, paraValue);
	if (paraValue == nullptr || paraValue.isEmpty() || paraValue == "")
	{
		QMessageBox::critical(NULL, QStringLiteral("错误"), QStringLiteral("%1不能为空, 请先设置%2").arg(paraName, paraName));
		return false;
	}
	return true;
}

bool HwUtils::checkSomeParam(QString paraName, QString paraValue, QString msg)
{
	bool sensitiveFlag = paraName.toLower().contains("token") || paraName.contains("凭证");
	if (sensitiveFlag && !HwUtils::logDebugRequired())
	{
		qInfo() << QString("check Param %1 : ******").arg(paraName);
	}
	else
	{
		qInfo() << QString("check Param %1 : %2").arg(paraName, paraValue);
	}

	if (paraValue == nullptr || paraValue.isEmpty() || paraValue == "")
	{
		QMessageBox::critical(NULL, QStringLiteral("错误"), QStringLiteral("%1").arg(msg));
		return false;
	}
	return true;
}

bool HwUtils::checkAiInferParams(QString machineId, QString productCode, QString tableName, QString cameraId)
{
	return HwUtils::checkSomeParam(QStringLiteral("工控机编号"), machineId, QStringLiteral("工控机编号不能为空，请先设置工控机编号"))
		&& HwUtils::checkSomeParam(QStringLiteral("产品编码"), productCode, QStringLiteral("产品编码不能为空，请先设置产品编码"))
		&& HwUtils::checkSomeParam(QStringLiteral("线体名称"), tableName, QStringLiteral("线体名称不能为空，请先设置线体名称"))
		&& HwUtils::checkSomeParam(QStringLiteral("相机ID"), cameraId, QStringLiteral("相机ID不能为空，请先设置相机ID"));
}


bool HwUtils::checkAiUrlReqParams(QString serialNumber, QString hostUrl, QString token, QString product)
{
	return HwUtils::checkSomeParam(QStringLiteral("工位编号"), serialNumber, QStringLiteral("工位编号息不能为空，请先设置工位编号"))
		&& HwUtils::checkSomeParam(QStringLiteral("服务主机URL"), hostUrl, QStringLiteral("服务主机URL不能为空，请先设置服务主机URL"))
		&& HwUtils::checkSomeParam(QStringLiteral("Token"), token, QStringLiteral("登录信息不能为空，请先登录"))
		&& HwUtils::checkSomeParam(QStringLiteral("产品信息"), product, QStringLiteral("产品信息不能为空，请先设置产品信息"));
}

bool HwUtils::checkGetPrductReqParams(QString serialNumber, QString hostUrl, QString token)
{
	return HwUtils::checkSomeParam(QStringLiteral("工位编号"), serialNumber, QStringLiteral("工位编号息不能为空，请先设置工位编号"))
		&& HwUtils::checkSomeParam(QStringLiteral("服务主机URL"), hostUrl, QStringLiteral("服务主机URL不能为空，请先设置服务主机URL"))
		&& HwUtils::checkSomeParam(QStringLiteral("Token"), token, QStringLiteral("登录信息不能为空，请先登录"));
}

#pragma endregion check_params